package config

import (
	config "ac-common-go/config"
	log "ac-common-go/glog"
	"reflect"
)

var ConfigInfo *Config

type Config struct {
	ConfigMap map[string]interface{}
	strcet    string
}

func (this *Config) Load() error {
	this.ConfigMap = make(map[string]interface{})
	conf, err := config.ReadConfigFile("./conf/sarama.conf")
	if err != nil {
		log.Errorf("read sarama config file failed:err[%v]", err)
		return err
	}
	defer this.Print()

	// section self
	this.ConfigMap["clientId"], err = conf.GetString("main", "client.id")
	if err != nil || !IfKeyInMap(this.ConfigMap, "clientId") {
		// set default value as empty string
		this.ConfigMap["clientId"] = "mirrormaker"
	}

	this.ConfigMap["brokers"], err = conf.GetString("main", "metadata.broker.list")
	if err != nil || !IfKeyInMap(this.ConfigMap, "brokers") {
		this.ConfigMap["brokers"] = "kafka1:9094,kafka2:9094,kafka3:9094"
	}

	this.ConfigMap["sendBufferSize"], err = conf.GetInt64("main", "send.buffer.size")
	if err != nil || !IfKeyInMap(this.ConfigMap, "sendBufferSize") {
		this.ConfigMap["sendBufferSize"] = 102400
	}

	this.ConfigMap["compressionCodec"], err = conf.GetString("main", "compression.codec")
	if err != nil || !IfKeyInMap(this.ConfigMap, "compressionCodec") {
		this.ConfigMap["compressionCodec"] = "none"
	}

	this.ConfigMap["flushByteCount"], err = conf.GetInt64("main", "flush.byte.count")
	if err != nil || !IfKeyInMap(this.ConfigMap, "flushByteCount") {
		this.ConfigMap["flushByteCount"] = 65535
	}

	this.ConfigMap["flushTimeout"], err = conf.GetString("main", "flush.timeout")
	if err != nil || !IfKeyInMap(this.ConfigMap, "flushTimeout") {
		this.ConfigMap["flushTimeout"] = "1s"
	}

	this.ConfigMap["batchSize"], err = conf.GetInt64("main", "batch.size")
	if err != nil || !IfKeyInMap(this.ConfigMap, "batchSize") {
		this.ConfigMap["batchSize"] = 10
	}

	this.ConfigMap["maxMessageBytes"], err = conf.GetInt64("main", "max.message.bytes")
	if err != nil || !IfKeyInMap(this.ConfigMap, "maxMessageBytes") {
		this.ConfigMap["maxMessageBytes"] = 1000000
	}

	this.ConfigMap["maxMessagesPerRequest"], err = conf.GetInt64("main", "max.messages.per.request")
	if err != nil || !IfKeyInMap(this.ConfigMap, "maxMessagesPerRequest") {
		this.ConfigMap["maxMessagesPerRequest"] = 100
	}

	this.ConfigMap["maxRetries"], err = conf.GetInt64("main", "max.retries")
	if err != nil || !IfKeyInMap(this.ConfigMap, "maxRetries") {
		this.ConfigMap["maxRetries"] = 3
	}

	this.ConfigMap["readTimeoutSec"], err = conf.GetInt64("main", "readTimeoutSec")
	if err != nil || !IfKeyInMap(this.ConfigMap, "readTimeoutSec") {
		this.ConfigMap["readTimeoutSec"] = 10
	}

	this.ConfigMap["writeTimeoutSec"], err = conf.GetInt64("main", "writeTimeoutSec")
	if err != nil || !IfKeyInMap(this.ConfigMap, "writeTimeoutSec") {
		this.ConfigMap["writeTimeoutSec"] = 10
	}

	this.ConfigMap["acks"], err = conf.GetInt64("main", "acks")
	if err != nil || !IfKeyInMap(this.ConfigMap, "acks") {
		this.ConfigMap["acks"] = 1
	}

	this.ConfigMap["retryBackoff"], err = conf.GetInt64("main", "retry.backoff")
	if err != nil || !IfKeyInMap(this.ConfigMap, "retryBackoff") {
		this.ConfigMap["retryBackoff"] = 500
	}

	this.ConfigMap["timeout"], err = conf.GetInt64("main", "timeout")
	if err != nil || !IfKeyInMap(this.ConfigMap, "timeout") {
		this.ConfigMap["timeout"] = 10
	}

	this.ConfigMap["enableTls"], err = conf.GetBool("main", "enable.tls")
	if err != nil || !IfKeyInMap(this.ConfigMap, "enableTls") {
		this.ConfigMap["enableTls"] = true
	}

	// SASL
	this.ConfigMap["enableSasl"], err = conf.GetBool("main", "enable.sasl")
	if err != nil || !IfKeyInMap(this.ConfigMap, "enableSasl") {
		this.ConfigMap["enableSasl"] = false
	}

	this.ConfigMap["saslUsername"], err = conf.GetString("main", "sasl.username")
	if err != nil || !IfKeyInMap(this.ConfigMap, "saslUsername") {
		this.ConfigMap["saslUsername"] = "juconn"
	}

	this.ConfigMap["saslPassword"], err = conf.GetString("main", "sasl.password")
	if err != nil || !IfKeyInMap(this.ConfigMap, "saslPassword") {
		this.ConfigMap["saslPassword"] = "changeit"
	}

	this.ConfigMap["saslMechanism"], err = conf.GetString("main", "sasl.mechanism")
	if err != nil || !IfKeyInMap(this.ConfigMap, "saslMechanism") {
		this.ConfigMap["saslMechanism"] = "SCRAM-SHA-512"
	}

	return nil
}

func IfKeyInMap(mapToCheck map[string]interface{}, key string) bool {
	if _, exists := mapToCheck[key]; exists {
		return true
	} else {
		return false
	}
}

func (this *Config) Print() {
	log.Infoln("start to print the sarama config")
	this.printConfigItem("main", "client_id", this.ConfigMap["clientId"])
	this.printConfigItem("main", "metadata.broker.list", this.ConfigMap["brokers"])
	this.printConfigItem("main", "send.buffer.size", this.ConfigMap["sendBufferSize"])
	this.printConfigItem("main", "compression.codec", this.ConfigMap["compressionCodec"])
	this.printConfigItem("main", "flush.byte.count", this.ConfigMap["flushByteCount"])
	this.printConfigItem("main", "flush.timeout", this.ConfigMap["flushTimeout"])
	this.printConfigItem("main", "batch.size", this.ConfigMap["batchSize"])
	this.printConfigItem("main", "readTimeoutSecl", this.ConfigMap["readTimeoutSec"])
	this.printConfigItem("main", "writeTimeoutSec", this.ConfigMap["writeTimeoutSec"])
	this.printConfigItem("main", "max.message.bytes", this.ConfigMap["maxMessageBytes"])
	this.printConfigItem("main", "max.messages.per.request", this.ConfigMap["maxMessagesPerRequest"])
	this.printConfigItem("main", "acks", this.ConfigMap["acks"])
	this.printConfigItem("main", "retry.backoff", this.ConfigMap["retryBackoff"])
	this.printConfigItem("main", "max.retries", this.ConfigMap["maxRetries"])
	this.printConfigItem("main", "timeout", this.ConfigMap["timeout"])
	this.printConfigItem("main", "enable.tls", this.ConfigMap["enableTls"])
	this.printConfigItem("main", "enable.sasl", this.ConfigMap["enableSasl"])
	this.printConfigItem("main", "sasl.username", this.ConfigMap["saslUsername"])
	this.printConfigItem("main", "sasl.password", this.ConfigMap["saslPassword"])
	this.printConfigItem("main", "sasl.mechanism", this.ConfigMap["saslMechanism"])

	log.Infoln("finish printing the sarama config")
}

func (this *Config) printConfigItem(section, name string, item interface{}) {
	log.Infof("config item info[%s.%s.(%v)]", section, name, reflect.TypeOf(item))
}
func Init() {
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("blacklist init failed: %v", err)
		}
	}()
	myConfig := new(Config)
	_ = myConfig.Load()
	myConfig.Print()
	ConfigInfo = myConfig
}
func GetConfigValue(key string) string {
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("get config value error: %s, %+v", key, err)
		}
	}()
	v, found := ConfigInfo.ConfigMap[key].(string)
	if !found {
		return ""
	}
	return v
}

func GetConfigInt64Value(key string) int64 {
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("get config value error: %s, %+v", key, err)
		}
	}()
	v, found := ConfigInfo.ConfigMap[key].(int64)
	if !found {
		return 0
	}
	return v
}

func GetConfigBoolValue(key string) bool {
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("get config value error: %s, %+v", key, err)
		}
	}()
	v, found := ConfigInfo.ConfigMap[key].(bool)
	if !found {
		return false
	}
	return v
}
